<template>
  <div ref="wrapRef" :class="getWrapperClass">
    <template v-if="getBindValues.searchForm">
      <AdSearchForm
        ref="formRef"
        v-bind="getSearchFormProps"
        @register="registerSearchForm"
        @search-click="handleSearchClick"
      />
    </template>
    <template v-else-if="getBindValues.formConfig">
      <BasicForm
        ref="formRef"
        submitOnReset
        v-bind="getFormProps"
        @register="registerForm"
        @submit="handleSearchInfoChange"
      >
        <template #[replaceFormSlotKey(item)]="data" v-for="item in getFormSlotKeys">
          <slot :name="item" v-bind="data || {}"></slot>
        </template>
      </BasicForm>
    </template>

    <List
      ref="listElRef"
      :grid="{ gutter: grid, xs: 1, sm: 2, md: 4, lg: grid, xl: grid, xxl: grid }"
      v-show="getEmptyDataIsShow"
      v-bind="getBindValues"
      @change="handleListChange"
    >
      <template #renderItem="{ item }">
        <ScrollContainer ref="scrollRef">
          <ListItem>
            <Card hoverable :bordered="false" class="p-2">
              <template #title v-if="$slots.title">
                <slot name="title" v-bind="item"></slot>
              </template>
              <template #cover v-if="$slots.cover">
                <div>
                  <slot name="cover" v-bind="item"></slot>
                </div>
              </template>
              <template #actions v-if="$slots.actions">
                <slot name="actions" v-bind="item"></slot>
              </template>

              <template v-if="$slots.content">
                <slot name="content" v-bind="item"></slot>
              </template>
            </Card>
          </ListItem>
          <Empty
            v-if="!(getBindValues?.dataSource?.length > 0)"
            :image="Empty.PRESENTED_IMAGE_SIMPLE"
          />
        </ScrollContainer>
      </template>

      <template #header v-if="$slots.header || !getHeaderProps.hideHeader">
        <slot name="header" v-if="$slots.header"></slot>
        <slot v-if="!getHeaderProps.hideHeader">
          <ListHeader v-bind="getHeaderProps">
            <template #headerTop v-if="$slots.headerTop">
              <slot name="headerTop"></slot>
            </template>
            <template #listTitle v-if="$slots.listTitle">
              <slot name="listTitle"></slot>
            </template>
            <template #toolbar>
              <slot name="toolbar"></slot>
              <Tooltip>
                <template #title>
                  <div class="w-50">每行显示数量</div>
                  <Slider id="slider" v-bind="sliderProp" v-model:value="grid" />
                </template>
                <TableOutlined />
              </Tooltip>
            </template>
          </ListHeader>
        </slot>
      </template>
      <template #footer v-if="$slots.footer || !getFooterProps.hideFooter">
        <slot name="footer" v-if="$slots.footer"></slot>
        <slot v-if="!getFooterProps.hideFooter">
          <ListFooter v-bind="getFooterProps" />
        </slot>
      </template>
    </List>

    <AdDetailFormModal @register="registerDetailModal" v-bind="getDetailFormProps" />
  </div>
</template>
<script lang="ts" setup>
  import { ref, computed, unref, toRaw, inject, watchEffect, useAttrs, useSlots } from 'vue';
  import { List, Empty, Tooltip, Slider, Card } from 'ant-design-vue';
  import { TableOutlined } from '@ant-design/icons-vue';
  import type { ListSize } from 'ant-design-vue/lib/list';
  import { PageWrapperFixedHeightKey } from '@/enums/pageEnum';
  import { BasicForm, useForm } from '@/components/Form/index';
  import { ScrollContainer } from '@/components/Container/index';

  import { useLoading } from '@/components/AdList/src/hooks/useLoading';
  import { usePagination } from '@/components/AdList/src/hooks/usePagination';
  import { useAdSearchForm } from '@/components/AdList/src/hooks/useAdSearchForm';
  import { useAdDataSource } from '@/components/AdList/src/hooks/useAdDataSource';
  // import { useListScroll } from '@/components/AdList/src/hooks/useListScroll';
  import { useListHeader } from '@/components/AdList/src/hooks/useListHeader';
  import { useListFooter } from '@/components/AdList/src/hooks/useListFooter';
  import { useListForm } from '@/components/AdList/src/hooks/useListForm';

  import { createListContext } from '@/components/AdList/src/hooks/useListContext';

  import ListHeader from '@/components/AdList/src/components/ListHeader.vue';
  import ListFooter from '@/components/AdList/src/components/ListFooter.vue';

  import { useDesign } from '@/hooks/web/useDesign';

  import { omit } from 'lodash-es';
  import { isBoolean, isFunction } from '@/utils/is';
  import { warn } from '@/utils/log';

  import { useModal } from '@/components/AdVxeModal';
  import { FormModeEnum } from '@/enums/formEnum';

  import { FilterGroup } from '@/utils/common/types';

  import type { AdListProps, AdListActionType } from '@/components/AdList/src/types/adList';

  import { useAdDetailForm } from '@/components/AdList/src/hooks/useAdDetailForm';
  import AdSearchForm from '@/components/AdTable/src/components/AdSearchForm.vue';
  import AdDetailFormModal from '@/components/AdTable/src/components/AdDetailFormModal.vue';

  import { adListProps } from '@/components/AdCardList/src/props';
  import { useSlider, grid } from './data';

  const ListItem = List.Item;

  defineOptions({ name: 'AdCardList' });
  const props = defineProps(adListProps);
  const emit = defineEmits(['fetch-success', 'fetch-error', 'register', 'change']);
  const attrs = useAttrs();
  const slots = useSlots();

  const { prefixCls } = useDesign('basic-table');
  const [registerForm] = useForm();

  const wrapRef = ref(null);
  const formRef = ref(null);
  const listElRef = ref(null);
  const listData = ref([]);

  // 获取slider属性
  const sliderProp = computed(() => useSlider());

  const innerPropsRef = ref<Partial<AdListProps>>();
  const getProps = computed(() => {
    return { ...props, ...unref(innerPropsRef) } as AdListProps;
  });

  const isFixedHeightPage = inject(PageWrapperFixedHeightKey, false);
  watchEffect(() => {
    unref(isFixedHeightPage) &&
      props.canResize &&
      warn(
        "'canResize' of List may not work in PageWrapper with 'fixedHeight' (especially in hot updates)",
      );
  });

  //设置加载
  const { getLoading, setLoading } = useLoading(getProps);
  //设置分页
  const { getPaginationInfo, getPagination, setPagination, setShowPagination, getShowPagination } =
    usePagination(getProps);
  //设置高级搜索表单
  const {
    getSearchFormProps,
    register: registerSearchForm,
    methods: searchFormActions,
  } = useAdSearchForm(getProps, getLoading);
  //设置高级数据源
  const {
    handleListChange: onListChange,
    getDataSourceRef,
    getDataSource,
    getRawDataSource,
    getSearchInfo,
    setListData,
    updateListDataRecord,
    deleteListDataRecord,
    insertListDataRecord,
    findListDataRecord,
    fetch,
    getRowKey,
    reload,
    // getAutoCreateKey,
    updateListData,
  } = useAdDataSource(
    getProps,
    {
      listData,
      getPaginationInfo,
      setPagination,
      setLoading,
      getSearchInfo: searchFormActions.getSearchInfo,
    },
    emit,
  );
  //处理列表更新
  function handleListChange(pagination: any, filters: any, sorter: any, extra: any) {
    onListChange(pagination, filters, sorter);
    emit('change', pagination, filters, sorter);
    // 解决通过useTable注册onChange时不起作用的问题
    const { onChange } = unref(getProps);
    onChange && isFunction(onChange) && onChange(pagination, filters, sorter, extra);
  }

  // //设置列表滚动
  // const { scrollRef, scrollTo, redoHeight } = useListScroll(
  //   getProps,
  //   wrapRef,
  //   formRef,
  //   listElRef,
  //   getDataSourceRef,
  // );
  //设置列表头部
  const { getHeaderProps } = useListHeader(getProps, slots);
  //设置列表底部
  const { getFooterProps } = useListFooter(getProps, listElRef, getDataSourceRef, undefined);
  //设置表单
  const { getFormProps, replaceFormSlotKey, getFormSlotKeys, handleSearchInfoChange } = useListForm(
    getProps,
    slots,
    fetch,
    getLoading,
  );
  //设置组件绑定值
  const getBindValues = computed(() => {
    const dataSource = unref(getDataSourceRef);
    const paginationInfo = toRaw(unref(getPaginationInfo));
    let propsData: any = {
      ...attrs,
      ...unref(getProps),
      loading: unref(getLoading),
      rowKey: unref(getRowKey),
      pagination: {
        ...(isBoolean(paginationInfo) ? {} : paginationInfo),
        onChange: async (page: number, pageSize: number) => {
          setPagination({
            current: page,
            pageSize,
          });
          await reload();
        },
      },
      // dataSource: [],
      dataSource: dataSource,
    };
    propsData = omit(propsData, ['class', 'onChange']);
    return propsData;
  });
  //获取布局类属性
  const getWrapperClass = computed(() => {
    const values = unref(getBindValues);
    return [
      prefixCls,
      attrs.class,
      {
        [`${prefixCls}-form-container`]: values.searchForm,
        // [`${prefixCls}-form-container`]: values.formConfig,
        [`${prefixCls}--inset`]: values.inset,
      },
    ];
  });
  //获取空数据时是否显示
  const getEmptyDataIsShow = computed(() => {
    const { emptyDataIsShow, searchForm } = unref(getProps);
    if (emptyDataIsShow || !searchForm) {
      return true;
    }
    return !!unref(getDataSourceRef).length;
  });
  //设置属性
  function setProps(props: Partial<AdListProps>) {
    innerPropsRef.value = { ...unref(innerPropsRef), ...props };
  }

  const listAction: AdListActionType = {
    reload,
    //@ts-ignore
    scrollTo: undefined,
    getPagination,
    setPagination,
    setShowPagination,
    getShowPagination,
    getRawDataSource,
    getSearchInfo,
    getListData: getDataSource,
    setListData,
    updateListData,
    updateListDataRecord,
    deleteListDataRecord,
    insertListDataRecord,
    findListDataRecord,
    setLoading,
    setProps,
    //@ts-ignore
    redoHeight: undefined,
    getSize: () => {
      return unref(getBindValues).size as ListSize;
    },
    emit,
    openDetailForm,
  };
  createListContext({ ...listAction, wrapRef, getBindValues });

  defineExpose({ listElRef, ...listAction });

  //详情表单
  const { getDetailFormProps } = useAdDetailForm(getProps, reload);
  // console.log('getDetailFormProps', getDetailFormProps);
  const [registerDetailModal, detailModalMethods] = useModal();

  emit('register', listAction, searchFormActions, detailModalMethods);

  /** 处理搜索按钮点击 */
  function handleSearchClick(info: FilterGroup) {
    const { handleSearchInfoFn } = unref(getProps);
    if (handleSearchInfoFn && isFunction(handleSearchInfoFn)) {
      info = handleSearchInfoFn(info) || info;
    }
    fetch({ searchInfo: info, page: 1 });
  }

  /** 打开详情表单 */
  function openDetailForm(formMode: FormModeEnum, record?: any) {
    //TODO:高级详情表单的弹窗
    detailModalMethods.openModal(true, {
      formMode: formMode,
      record: record,
    });
  }
</script>

<style lang="less" scoped>
  @border-color: #cecece4d;

  @prefix-cls: ~'@{namespace}-basic-table';

  .@{prefix-cls} {
    max-width: 100%;
    height: 100%;
    //padding: 8px;

    .ant-list-item {
      border-bottom: unset !important;
      background-color: @component-background;

      &:hover {
        background-color: @app-content-background;
      }
    }

    .ant-empty-image svg {
      // margin-top: 160px;
      vertical-align: middle;
    }

    &-form-container {
      // padding: 16px;

      .ant-form {
        width: 100%;
        // margin-bottom: 16px;
        padding: 12px 10px 6px;
        border-radius: 2px;
        background-color: @component-background;
      }
    }

    .ant-tag {
      margin-right: 0;
    }

    .ant-list {
      padding: 6px;
      border-radius: 2px;
      background-color: @component-background;

      &-header {
        display: flex;
        align-items: center;
        // padding: 8px 6px;
        // border-bottom: none;
        justify-content: space-between;
        min-height: 40px;
        padding: 0 0 8px !important;
      }

      &-footer {
        padding: 0;

        .ant-table-wrapper {
          padding: 0;
        }

        table {
          border: none !important;
        }

        .ant-table-body {
          overflow-x: hidden !important;
          //  overflow-y: scroll !important;
        }

        td {
          padding: 12px 8px;
        }
      }

      // .ant-table.ant-table-bordered .ant-table-title {
      //   border: none !important;
      // }
    }

    .ant-table-wrapper .ant-pagination {
      margin: 10px 0 0;
    }

    &--inset {
      .ant-table-wrapper {
        padding: 0;
      }
    }
  }
</style>
